package com.jdpc.weparty.service.activity.signup

import com.jdpc.weparty.entity.Activity
import com.jdpc.weparty.entity.SignUpActivity
import com.jdpc.weparty.entity.User
import com.jdpc.weparty.reposity.ActivityRepository
import com.jdpc.weparty.repository.SignUpActivityRepository
import com.jdpc.weparty.reposity.UserRepository
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.Page
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service

@Service
class SignUpActivityServiceImpl : SignUpActivityService {
    @Autowired
    lateinit var signUpActivityRepository: SignUpActivityRepository

    @Autowired
    lateinit var userRepository: UserRepository

    @Autowired
    lateinit var activityRepository: ActivityRepository

    override fun getActivityForm(userId: Int): List<Activity> =
            signUpActivityRepository.findByUserId(userId).map {
                activityRepository.findById(it.activityId).get()
            }

    override fun getActivityForm(userId: Int, pageable: Pageable): Page<SignUpActivity> {
        return signUpActivityRepository.findByUserId(userId, pageable)
    }


    override fun getActivityForm(userId: Int, passed: Boolean?): List<Activity> =
            when (passed) {
                null -> {
                    signUpActivityRepository.findByUserIdAndPassedIsNull(userId).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
                true -> {
                    signUpActivityRepository.findByUserIdAndPassedTrue(userId).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
                false -> {
                    signUpActivityRepository.findByUserIdAndPassedFalse(userId).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
            }


    override fun getActivityForm(userId: Int, passed: Boolean?, pageable: Pageable): Page<Activity> =
            when (passed) {
                null -> {
                    signUpActivityRepository.findByUserIdAndPassedIsNull(userId, pageable).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
                true -> {
                    signUpActivityRepository.findByUserIdAndPassedTrue(userId, pageable).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
                false -> {
                    signUpActivityRepository.findByUserIdAndPassedFalse(userId, pageable).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
            }

    override fun getUserForm(aId: Int): List<User> {
        return signUpActivityRepository.findByActivityId(aId).map {
            userRepository.findById(it.userId).get()
        }
    }


    override fun getUserForm(aId: Int, passed: Boolean?): List<User> =
            when (passed) {
                null -> {
                    signUpActivityRepository.findByActivityIdAndPassedIsNull(aId).map {
                        userRepository.findById(it.userId).get()
                    }
                }
                true -> {
                    signUpActivityRepository.findByActivityIdAndPassedTrue(aId).map {
                        userRepository.findById(it.userId).get()
                    }
                }
                false -> {
                    signUpActivityRepository.findByActivityIdAndPassedFalse(aId).map {
                        userRepository.findById(it.userId).get()
                    }
                }
            }


    override fun getUserForm(aId: Int, passed: Boolean?, pageable: Pageable): Page<User> =
            when (passed) {
                null -> {
                    signUpActivityRepository.findByActivityIdAndPassedIsNull(aId, pageable).map {
                        userRepository.findById(it.userId).get()
                    }
                }
                true -> {
                    signUpActivityRepository.findByActivityIdAndPassedTrue(aId, pageable).map {
                        userRepository.findById(it.userId).get()
                    }
                }
                false -> {
                    signUpActivityRepository.findByActivityIdAndPassedFalse(aId, pageable).map {
                        userRepository.findById(it.userId).get()
                    }
                }
            }


    override fun signUp(userId: Int, activityId: Int): Pair<Boolean, Boolean?> {
        val activities = signUpActivityRepository.findByUserId(userId)
        activities.forEach {
            if (it.activityId == activityId) {
                return Pair(true, it.passed)
            }
        }
        val sua = SignUpActivity().apply {
            this.userId = userId
            this.activityId = activityId
            this.passed = null
        }
        signUpActivityRepository.save(sua)
        return Pair(false, null)
    }

    override fun pass(userId: Int, activityId: Int, passed: Boolean) {
        val sua = signUpActivityRepository.findByActivityIdAndUserId(activityId, userId)
        sua.passed = passed
        signUpActivityRepository.save(sua)
    }

    override fun passAll(activityId: Int, passed: Boolean) {
        val suas = signUpActivityRepository.findByActivityIdAndPassedIsNull(activityId)
        suas.forEach {
            it.passed = passed
            signUpActivityRepository.save(it)
        }
    }

    override fun getSignJoiners(activityId: Int, sign: Boolean): List<User> =
            when (sign) {
                true -> {
                    signUpActivityRepository.findByActivityIdAndSignTrue(activityId).map {
                        userRepository.findById(it.userId).get()
                    }

                }
                false -> {
                    signUpActivityRepository.findByActivityIdAndSignFalse(activityId).map {
                        userRepository.findById(it.userId).get()
                    }
                }
            }


    override fun getSignJoiners(activityId: Int, sign: Boolean, pageable: Pageable): Page<User> =
            when (sign) {
                true -> {
                    signUpActivityRepository.findByActivityIdAndSignTrue(activityId, pageable).map {
                        userRepository.findById(it.userId).get()
                    }
                }
                false -> {
                    signUpActivityRepository.findByActivityIdAndSignFalse(activityId, pageable).map {
                        userRepository.findById(it.userId).get()
                    }
                }
            }

    override fun getSignActivities(userId: Int, sign: Boolean): List<Activity> =
            when (sign) {
                true -> {
                    signUpActivityRepository.findByUserIdAndSignTrue(userId).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
                false -> {
                    signUpActivityRepository.findByUserIdAndSignFalse(userId).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
            }

    override fun getSignActivities(userId: Int, sign: Boolean, pageable: Pageable): Page<Activity> =
            when (sign) {
                true -> {
                    signUpActivityRepository.findByUserIdAndSignTrue(userId, pageable).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
                false -> {
                    signUpActivityRepository.findByUserIdAndSignFalse(userId, pageable).map {
                        activityRepository.findById(it.activityId).get()
                    }
                }
            }

    override fun signIn(userId: Int, activityId: Int) {
        val sua = signUpActivityRepository.findByActivityIdAndUserId(activityId, userId)
        sua.sign = true
        signUpActivityRepository.save(sua)
    }
}